package com.bucket.cloud.common.starter;

import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.bucket.cloud.common.core.annotation.ResourceAnnotationScan;
import com.bucket.cloud.common.core.config.BucketCommonProperties;
import com.bucket.cloud.common.core.config.BucketIdGenProperties;
import com.bucket.cloud.common.core.exception.BucketGlobalExceptionHandler;
import com.bucket.cloud.common.core.exception.BucketRestResponseErrorHandler;
import com.bucket.cloud.common.core.filter.XssFilter;
import com.bucket.cloud.common.core.gen.SnowflakeIdGenerator;
import com.bucket.cloud.common.core.health.DbHealthIndicator;
import com.bucket.cloud.common.core.security.http.OpenRestTemplate;
import com.bucket.cloud.common.core.security.oauth2.client.OpenOAuth2ClientProperties;
import com.bucket.cloud.common.core.util.SpringContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.client.RestTemplate;

/**
 * 默认配置类
 *
 * @author cyq
 */
@Slf4j
@Configuration
@EnableConfigurationProperties({BucketCommonProperties.class, BucketIdGenProperties.class, OpenOAuth2ClientProperties.class})
public class AutoConfiguration {


    /**
     * xss过滤
     * body缓存
     *
     * @return
     */
    @Bean
    public FilterRegistrationBean XssFilter() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new XssFilter());
        log.info("XssFilter [{}]", filterRegistrationBean);
        return filterRegistrationBean;
    }

    /**
     * 分页插件
     */
    @ConditionalOnMissingBean(PaginationInterceptor.class)
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        log.info("PaginationInterceptor [{}]", paginationInterceptor);
        return paginationInterceptor;
    }

    /**
     * 默认加密配置
     *
     * @return
     */
    @Bean
    @ConditionalOnMissingBean(BCryptPasswordEncoder.class)
    public BCryptPasswordEncoder bCryptPasswordEncoder() {
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        log.info("BCryptPasswordEncoder [{}]", encoder);
        return encoder;
    }


    /**
     * Spring上下文工具配置
     *
     * @return
     */
    @Bean
    @ConditionalOnMissingBean(SpringContextHolder.class)
    public SpringContextHolder springContextHolder() {
        SpringContextHolder holder = new SpringContextHolder();
        log.info("SpringContextHolder [{}]", holder);
        return holder;
    }

    /**
     * 统一异常处理配置
     *
     * @return
     */
    @Bean
    @ConditionalOnMissingBean(BucketGlobalExceptionHandler.class)
    public BucketGlobalExceptionHandler exceptionHandler() {
        BucketGlobalExceptionHandler exceptionHandler = new BucketGlobalExceptionHandler();
        log.info("BucketGlobalExceptionHandler [{}]", exceptionHandler);
        return exceptionHandler;
    }

    /**
     * ID生成器配置
     *
     * @param properties
     * @return
     */
    @Bean
    @ConditionalOnMissingBean(BucketIdGenProperties.class)
    public SnowflakeIdGenerator snowflakeIdWorker(BucketIdGenProperties properties) {
        SnowflakeIdGenerator snowflakeIdGenerator = new SnowflakeIdGenerator(properties.getWorkId(), properties.getCenterId());
        log.info("SnowflakeIdGenerator [{}]", snowflakeIdGenerator);
        return snowflakeIdGenerator;
    }


    /**
     * 自定义注解扫描
     *
     * @return
     */
    @Bean
    @ConditionalOnMissingBean(ResourceAnnotationScan.class)
    public ResourceAnnotationScan resourceAnnotationScan(AmqpTemplate amqpTemplate) {
        ResourceAnnotationScan scan = new ResourceAnnotationScan(amqpTemplate);
        log.info("ResourceAnnotationScan [{}]", scan);
        return scan;
    }

    /**
     * 自定义Oauth2请求类
     *
     * @param bucketCommonProperties
     * @return
     */
    @Bean
    @ConditionalOnMissingBean(OpenRestTemplate.class)
    public OpenRestTemplate openRestTemplate(BucketCommonProperties bucketCommonProperties) {
        OpenRestTemplate restTemplate = new OpenRestTemplate(bucketCommonProperties);
        //设置自定义ErrorHandler
        restTemplate.setErrorHandler(new BucketRestResponseErrorHandler());
        log.info("bean [{}]", restTemplate);
        return restTemplate;
    }

    @Bean
    public RestTemplate restTemplate() {
        RestTemplate restTemplate = new RestTemplate();
        //设置自定义ErrorHandler
        restTemplate.setErrorHandler(new BucketRestResponseErrorHandler());
        log.info("RestTemplate [{}]", restTemplate);
        return restTemplate;
    }

    @Bean
    @ConditionalOnMissingBean(DbHealthIndicator.class)
    public DbHealthIndicator dbHealthIndicator() {
        DbHealthIndicator dbHealthIndicator = new DbHealthIndicator();
        log.info("DbHealthIndicator [{}]", dbHealthIndicator);
        return dbHealthIndicator;
    }

}
